//   Copyright 2012,2013 Vaughn Vernon
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

package com.saasovation.agilepm.domain.model.team;

import java.util.Date;

import com.saasovation.agilepm.domain.model.ValueObject;

/**
 * @值对象：成员改变追踪器
 * @author learn
 */
public class MemberChangeTracker extends ValueObject {

    /**
     * 邮件地址改变日期
     */
    private Date emailAddressChangedOn;
    /**
     * 启用日期
     */
    private Date enablingOn;
    /**
     * 名字改变日期
     */
    private Date nameChangedOn;

    /**
     * 能否改变邮件地址
     * @param asOfDate 截至日期
     * @return 返回能否改变邮件地址
     */
    public boolean canChangeEmailAddress(Date asOfDate) {
        // 如果 当前邮件地址改变日期是在指定截至日期之前，则能改变；否则不能改变
        return this.emailAddressChangedOn().before(asOfDate);
    }

    /**
     * 能否改变名字
     * @param asOfDate	截至日期
     * @return	返回能否改变名字
     */
    public boolean canChangeName(Date asOfDate) {
        // 如果 当前名字改变日期是在指定截至日期之前，则能改变；否则不能改变
        return this.nameChangedOn().before(asOfDate);
    }

    /**
     * 能否切换启用
     * @param asOfDate 截至日期
     * @return 返回能否切换启用
     */
    public boolean canToggleEnabling(Date asOfDate) {
        // 如果 当前切换于（日期）是在截至日期之前，则能改变；否则不能改变
        return this.enablingOn().before(asOfDate);
    }

    /**
     * 获取邮件地址改变于（截至日期）的追踪器
     * @param asOfDate 截至日期
     * @return 返回邮件地址改变于（截至日期）的追踪器
     */
    public MemberChangeTracker emailAddressChangedOn(Date asOfDate) {
        // 使用 启用日期、名字改变日期、截至日期 构造追踪器，并返回
        return new MemberChangeTracker(this.enablingOn(), this.nameChangedOn(), asOfDate);
    }

    /**
     * 获取启用于（截至日期）的追踪器
     * @param asOfDate 截至日期
     * @return 返回启用于（截至日期）的追踪器
     */
    public MemberChangeTracker enablingOn(Date asOfDate) {
        // 使用 截至日期、名字改变日期、邮件地址改变日期 构造追踪器，并返回
        return new MemberChangeTracker(asOfDate, this.nameChangedOn(), this.emailAddressChangedOn());
    }

    /**
     * 获取名字改变于（截至日期）的追踪器
     * @param asOfDate 截至日期
     * @return 返回名字改变于（截至日期）的追踪器
     */
    public MemberChangeTracker nameChangedOn(Date asOfDate) {
        // 使用 启用日期、截至日期、邮件地址改变日期构造追踪器，并返回
        return new MemberChangeTracker(this.enablingOn(), asOfDate, this.emailAddressChangedOn());
    }

    @Override
    public boolean equals(Object anObject) {
        boolean equalObjects = false;

        if (anObject != null && this.getClass() == anObject.getClass()) {
            MemberChangeTracker typedObject = (MemberChangeTracker) anObject;
            equalObjects =
                    this.enablingOn().equals(typedObject.enablingOn()) &&
                            this.nameChangedOn().equals(typedObject.nameChangedOn()) &&
                            this.emailAddressChangedOn().equals(typedObject.emailAddressChangedOn());
        }

        return equalObjects;
    }

    @Override
    public int hashCode() {
        int hashCodeValue =
                + (8705 * 67)
                        + this.enablingOn().hashCode()
                        + this.nameChangedOn().hashCode()
                        + this.emailAddressChangedOn().hashCode();

        return hashCodeValue;
    }

    /**
     * 由以下参数构造成员改变追踪器
     * @param anEnablingOn				启用日期
     * @param aNameChangedOn			名字改变日期
     * @param anEmailAddressChangedOn	邮件地址改变日期
     */
    protected MemberChangeTracker(
            Date anEnablingOn,
            Date aNameChangedOn,
            Date anEmailAddressChangedOn) {
        // 调用父类默认构造器
        this();

        this.setEmailAddressChangedOn(anEmailAddressChangedOn);
        this.setEnablingOn(anEnablingOn);
        this.setNameChangedOn(aNameChangedOn);
    }

    /**
     * 根据已有追踪器，构造新的追踪器
     * @param aMemberChangeTracker 成员改变追踪器
     */
    protected MemberChangeTracker(MemberChangeTracker aMemberChangeTracker) {
        this(aMemberChangeTracker.enablingOn(),
                aMemberChangeTracker.nameChangedOn(),
                aMemberChangeTracker.emailAddressChangedOn());
    }

    /**
     * 成员改变追踪器
     */
    private MemberChangeTracker() {
        // 调用父类的默认构造器
        super();
    }

    /**
     * 获取邮件地址改变日期
     * @return 返回邮件地址改变日期
     */
    private Date emailAddressChangedOn() {
        return this.emailAddressChangedOn;
    }

    /**
     * 获取启用日期
     * @return 返回启用日期
     */
    private Date enablingOn() {
        return this.enablingOn;
    }

    /**
     * 获取名字改变日期
     * @return 返回名字改变日期
     */
    private Date nameChangedOn() {
        return this.nameChangedOn;
    }

    /**
     * 设置邮件地址改变日期
     * @param anEmailAddressChangedOn 邮件地址改变日期
     */
    private void setEmailAddressChangedOn(Date anEmailAddressChangedOn) {
        this.assertArgumentNotNull(anEmailAddressChangedOn, "Email address changed on date must be provided.");

        this.emailAddressChangedOn = anEmailAddressChangedOn;
    }

    /**
     * 设置启用日期
     * @param anEnablingOn 启用日期
     */
    private void setEnablingOn(Date anEnablingOn) {
        this.assertArgumentNotNull(anEnablingOn, "Enabling date must be provided.");

        this.enablingOn = anEnablingOn;
    }

    /**
     * 设置名字改变日期
     * @param aNameChangedOn 名字改变日期
     */
    private void setNameChangedOn(Date aNameChangedOn) {
        this.assertArgumentNotNull(aNameChangedOn, "Name changed on date must be provided.");

        this.nameChangedOn = aNameChangedOn;
    }
}
